/*********************************************************************************
 *      Copyright:  (C) 2020 wangruijie<1046299465@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  main_serial.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(09/07/20)
 *         Author:  wangruijie <1046299465@qq.com>
 *      ChangeLog:  1, Release initial version on "09/07/20 06:07:30"
 *                 
 ********************************************************************************/
#include "serial.h"
#include "main_serial.h"

int main(int argc, char **argv)
{
    int                 opt = -1 ;
    char                *name = NULL ;
    long                baudrate = 115200 ;
    int                 databit = 8 ;
    char                parity = 'N' ;
    int                 stopbit = 1 ;
    int                 timeout = 0 ;
    char                *program_name ;
    serial_t            *serial;
    int                 fd_com = -1 ;
    fd_set              rset ;
    time_t              ticks ; 
    int                 rv = -1 ;
    char                rbuf[BUF_LEN] ;

    program_name = basename(argv[0]) ;

    const char *short_opts = "b:d:p:s:f:n:h";
    const struct option long_opts[] =   {
        {"help", no_argument, NULL, 'h'}, 
        {"baudrate", required_argument, NULL, 'b'},
        {"data", required_argument, NULL, 'd'},
        {"parity", required_argument, NULL, 'p'},
        {"stop", required_argument, NULL, 's'},
        {"timeout", required_argument, NULL, 't'},
        {"name", required_argument, NULL, 'n'},

        {0, 0, 0, 0} 
    };

    while ((opt= getopt_long(argc, argv, short_opts, long_opts,NULL)) != -1)
    {
        switch (opt)
        {
            case 'b':
                baudrate = atoi(optarg) ;
                break;

            case 'd':
                databit = atoi(optarg) ;
                break;

            case 's':
                stopbit = atoi(optarg) ;
                break;

            case 'p':
                parity = optarg[0] ;
                break;

            case 't':
                timeout = atoi(optarg) ;
                break;

            case 'n':
                name = optarg ;
                break;

            case 'h':
                print_usage(program_name) ;
                break;
        }
    }

    if(name == NULL)
    {
        printf("Please input TTY name , For example: \"%s -n /dev/ttyUSB4\"\n", program_name) ;
        print_usage(program_name) ;
        return -1;
    }

    serial = comport_init(name, baudrate,databit,parity,stopbit) ;
    if(serial < 0)
    {
        printf("comport_init() failed\n") ;
        return -2;
    }

    fd_com = comport_open(serial) ;
    if(fd_com<0)
    {
        printf("Open_comport() Failed\n") ;
        return -3;
    }

    signal(SIGINT, sighandler) ;
    fflush(stdin); //刷新标准输入缓冲区,把输入缓冲区里的东西丢弃
    while(!g_stop)
    {
        FD_ZERO(&rset) ;
        FD_SET(STDIN_FILENO, &rset) ;
        FD_SET(fd_com, &rset) ;
        rv = select(fd_com+1, &rset, NULL, NULL, NULL) ;
        if(rv<0)
        {
            printf("select() failed: %s\n", strerror(errno)) ;
            goto cleanup;
        }

        if(rv == 0)
        {
            printf("select() time out!\n") ;
            goto cleanup;
        }

        ticks = time(NULL) ;

        int   i = 0;
        int   j = 0;
        char  buf[64];
        memset(buf, 0, 64);

        if( FD_ISSET(STDIN_FILENO, &rset) )
        {
            memset(rbuf, 0, sizeof(rbuf)) ;
            fgets(rbuf, sizeof(rbuf), stdin) ;
            for(i; i<strlen(rbuf); i++)
            {
                if(rbuf[i] != '\n')
                {
                    buf[j] = rbuf[i];
                    j++;
                }
            }
            strncat(buf, "\r", 64);
            /*for(i = 0; i < strlen(buf); i++)
            {
                printf("%02x\n", buf[i]);
            }*/
            if( write_comport(serial, buf, strlen(buf)) < 0)
            {
                printf("write to other side failure :%s\n", strerror(errno)) ;
                break;
            }
            fflush(stdin); //刷新标准输入缓冲区,把输入缓冲区里的东西丢弃
        }
        if( FD_ISSET(fd_com, &rset) )
        {
            memset(buf, 0, sizeof(buf)) ;
            rv = read_comport(serial, buf, BUF_LEN,timeout) ;
            if(rv<0)
            {
                printf("read() error: %s\n", strerror(errno)) ;
                break;
            }
//            printf("%.24s\n",ctime(&ticks)) ;
            printf("%s", buf) ;
        }
    }
    printf("Program %s exit!\n", program_name) ;

cleanup:
    comport_term(serial) ;
    return 0;
}
